package cn.fansunion.leecode.isNumber;

/**
 * 374. 猜数字大小 猜数字游戏的规则如下：
 * 
 * 每轮游戏，我都会从 1 到 n 随机选择一个数字。 请你猜选出的是哪个数字。 如果你猜错了，我会告诉你，你猜测的数字比我选出的数字是大了还是小了。 <br/>
 * 你可以通过调用一个预先定义好的接口 ： int guess(int num) 来获取猜测结果，返回值一共有 3 种可能的情况（-1，1 或 0）： <br/>
 * 
 * -1：我选出的数字比你猜的数字小 pick < num 1：我选出的数字比你猜的数字大 pick > num 0：我选出的数字和你猜的数字一样。
 * 恭喜！你猜对了！pick == num 返回我选出的数字。 <br/>
 * 
 * 来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/guess-number-higher-or-lower 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * 
 * @author wen.lei@brgroup.com
 *
 *         2022-2-19
 */
public class GuessNumberHigherOrLower {

    private int pick;

    public GuessNumberHigherOrLower(int pick) {
        this.pick = pick;
    }

    /*  示例 1：
    
    输入：n = 10, pick = 6
    输出：6
    示例 2：
    
    输入：n = 1, pick = 1
    输出：1
    示例 3：
    
    输入：n = 2, pick = 1
    输出：1
    示例 4：
    
    输入：n = 2, pick = 2
    输出：2
     
    
    提示：
    
    1 <= n <= 231 - 1
    1 <= pick <= n*/
    // 0 1 2 3 4 5 6 7 8 9
    // 1 2 3 4
    /**
     * 数据源，本质是从0到n的一个数组。因为数字是连续的，不存在“二分查找”的一个“细节问题” TODO
     * 
     * @param n
     * @return
     */
    public int guessNumber(int n) {
        if (pick < 0 || pick > n) {
            throw new IllegalArgumentException("pick<0 || pick >n");
        }
        int result = 0;
        int min = 0;
        int max = n;
        int num = (min + max) / 2;
        while ((result = guess(num)) != 0 /*&& min < max*/) {
            if (result == 1) {
                min = num + 1;
            } else if (result == -1) {
                max = num - 1;
            }
            // 越界了 num = (min + max) / 2;
            num = min + (max - min) / 2;
        }
        /*        if (min >= max) {
            return min;
        }
        */ return num;

    }

    /**
     * Forward declaration of guess API.
     * 
     * @param num
     *            your guess
     * @return -1 if num is lower than the guess number 1 if num is higher than the guess number otherwise return 0 int
     *         guess(int num);
     */
    public int guess(int num) {
        if (pick < num) {
            return -1;
        } else if (pick > num) {
            return 1;
        } else {
            return 0;
        }

    }
}
